//package com.godyao.service.impl;
//
//import cn.hutool.core.date.DateUtil;
//import com.godyao.entity.UrlMapInfo;
//import com.godyao.repository.UrlMapInfoRepository;
//import com.godyao.service.ShortUrlService;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.stereotype.Service;
//
//import java.util.Date;
//import java.util.Optional;
//import java.util.Stack;
//import java.util.function.Function;
//
///**
// * 分布式id生成方式，不用每次都去请求DB拿到自增值，
// * 可以在每台应用机器内缓存一个区间，这样大大降低DB的负载，
// * 唯一缺陷是因为机器重启内存断电导致的中间序列可能断，
// * 但是这对于业务来说不重要。
// * @author godyao
// * @date 2022/3/5
// */
//@Service
//public class ShortUrlServiceImpl implements ShortUrlService {
//    private static final int DEFAULT_EXPIRE_DAYS = 3;
//
//    private static final String DEFAULT_DIRECT_URL = "http://www.baidu.com";
//
//    private static final String DOMAIN = "http://micro/";
//
//    /**
//     * 内存缓存的最大值
//     */
//    private long maxId = 0L;
//
//    /**
//     * 步长，每次DB获取的长度
//     */
//    private static final int DELTA = 1;
//
//    @Autowired
//    private UrlMapInfoRepository urlMapInfoRepository;
//
//    @Override
//    public String shorten(String url, Date expireTime) {
//        if (null == expireTime) {
//            expireTime = DateUtil.offsetDay(DateUtil.date(), DEFAULT_EXPIRE_DAYS);
//        }
//        // 每DELTA次 请求一次数据库拿到最大id （0- -10） （11 - 1） （21 - 11）如果中间程序崩溃 可能会浪费小于等于DELTA个id
//        if (maxId % DELTA == 0){
//            maxId = getMaxId();
//        //System.out.println("maxId=============" + maxId);
//        }
//        long id = maxId--;
//        // 转换成62进制的4位短链接
//        String s = parseInteger2Char(id, 62, (o) -> {
//            if (o <= 9) return (char) ('0' + o);
//            if (o >= 10 && o < 36) return (char) ('a' + (o - 10));
//            return (char) ('A' + (o - 36));
//        });
//        String ret = DOMAIN + s;
//        // insertTODB
//        urlMapInfoRepository.save(UrlMapInfo.builder().longUrl(url).shortUrl(ret).createTime(new Date()).expireTime(expireTime).build());
//        //dbMap.put(ret, str);
//        return ret;
//    }
//
//    @Override
//    public String redirect(String shortUrl) {
//        return Optional.ofNullable(urlMapInfoRepository.findActiveLongUrlByShortUrl(shortUrl))
//                .orElse(DEFAULT_DIRECT_URL);
//    }
//
//    private String parseInteger2Char(Long id, int hex, Function<Long, Character> mapperFunction) {
//        // 进制转换
//        final Stack<Long> stack = new Stack();
//        while (true) {
//            long n = id % hex;
//            stack.push(n);
//            id /= hex;
//            if (id < hex) {
//                stack.push(id);
//                break;
//            }
//        }
//        // 短链接字符串映射
//        final StringBuffer stringBuffer = new StringBuffer();
//        while (!stack.isEmpty()) {
//            stringBuffer.append(mapperFunction.apply(stack.pop()));
//        }
//        final String s = stringBuffer.toString();
//        return s;
//    }
//
//    private synchronized Long getMaxId() {
//        return Optional.ofNullable(urlMapInfoRepository.findMaxId()).orElse(0L) + DELTA;
//    }
//}
